package com.thwj.project.app.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thwj.common.exception.ServiceException;
import com.thwj.common.utils.DistanceUtil;
import com.thwj.common.utils.StringUtils;
import com.thwj.framework.mybatis_plus.GeoUtil;
import com.thwj.framework.security.LoginUser;
import com.thwj.framework.web.service.TokenService;
import com.thwj.project.amap.dto.AppLocationDTO;
import com.thwj.project.app.api.param.MerchantParam;
import com.thwj.project.app.api.param.MerchantSearchParam;
import com.thwj.project.app.api.vo.MerchantTagVO;
import com.thwj.project.app.api.vo.MerchantVO;
import com.thwj.project.app.convert.MerchantConvert;
import com.thwj.project.biz.domain.ActivityCategory;
import com.thwj.project.biz.domain.Merchant;
import com.thwj.project.biz.domain.MerchantApply;
import com.thwj.project.biz.domain.MerchantProduct;
import com.thwj.project.biz.enums.AuditStatusEnum;
import com.thwj.project.biz.enums.MerchantProductStatusEnum;
import com.thwj.project.biz.enums.MerchantStatusEnum;
import com.thwj.project.biz.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Transactional
@Service
public class AppMerchantService {

    @Autowired
    IUserService userService;
    @Autowired
    IMerchantService merchantService;
    @Autowired
    IMerchantApplyService merchantApplyService;
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    IActivityCategoryService activityCategoryService;
    @Autowired
    AppAreaService appAreaService;
    @Autowired
    TokenService tokenService;
    @Autowired
    IMerchantProductService merchantProductService;
    @Autowired
    AppProductService appProductService;


    public MerchantVO getMerchantInfo(LoginUser loginUser) {
        // 读取修改申请表
        MerchantApply merchantApply = merchantApplyService.getOne(
                new QueryWrapper<MerchantApply>()
                        .eq("user_id", loginUser.getUserId()).orderByDesc("id"),false);
        MerchantVO merchantVO = new MerchantVO();
        if (merchantApply != null) {
            BeanUtils.copyProperties(merchantApply, merchantVO);
            // 部分字段单独处理
            List<MerchantTagVO> tagVOList = MerchantConvert.convertTagList(merchantApply.getTagIdList());
            merchantVO.setTagVOList(tagVOList);
        }else {
            // 部分字段单独处理
            List<MerchantTagVO> tagVOList = MerchantConvert.convertTagList(null);
            merchantVO.setTagVOList(tagVOList);
        }
        //
        return merchantVO;
    }


    /**
     * 商家提交申请
     * @param merchantParam
     * @param loginUser
     */
    public void commitMerchantApply(MerchantParam merchantParam, LoginUser loginUser) {
        //检查用户最近的记录是否有审核中的
        MerchantApply old = merchantApplyService.getOne(
                new QueryWrapper<MerchantApply>()
                        .eq("status", AuditStatusEnum.auditing.getValue())
                        .eq("user_id", loginUser.getUserId())
        );
        if (old != null) {
            throw new ServiceException("已存在待审核的商家信息");
        }

        MerchantApply merchantApply = new MerchantApply();
        BeanUtils.copyProperties(merchantParam,merchantApply);
        merchantApply.setId(null);
        merchantApply.setTagIdList(merchantParam.getTagJson());
        // 补充活动分类
        ActivityCategory activityCategory = activityCategoryService.getById(merchantParam.getCategoryId());
        if (activityCategory != null) {
            merchantApply.setCategoryName(activityCategory.getName());
        }
        // 补充当前用户
        merchantApply.setUserId(loginUser.getUserId());
        // 补充经纬度换省市区
        String lngLat = merchantParam.getLongitude() + "," + merchantParam.getLatitude();
        AppLocationDTO appLocationDTO = appAreaService.getAppLocationVoByLngLat(lngLat);
        if(appLocationDTO == null) {
            throw new ServiceException("地址转换错误，请检查经纬度是否正确");
        }
        merchantApply.setLocation(GeoUtil.getWgs84Point(merchantParam.getLatitude(),merchantParam.getLongitude()));
        merchantApply.setCodeProv(appLocationDTO.getCodeProv());
        merchantApply.setCodeCity(appLocationDTO.getCodeCity());
        merchantApply.setNameCity(appLocationDTO.getNameCity());
        merchantApply.setNameProv(appLocationDTO.getNameProv());
        merchantApply.setCodeProv(appLocationDTO.getCodeProv());
        merchantApply.setCodeDistrict(appLocationDTO.getCodeDistrict());
        merchantApply.setNameDistrict(appLocationDTO.getNameDistrict());
        // 设置为审核中状态
        merchantApply.setStatus(AuditStatusEnum.auditing.getValue());

        merchantApplyService.save(merchantApply);
        return;
    }

    public void updateMerchant(MerchantParam merchantParam, LoginUser loginUser) {
        // todo
    }

    public Page<MerchantVO> getMerchantPage(Page page, MerchantSearchParam searchParam) {
        //获取授权的经纬度
        Double lngLatArray[] = tokenService.getLngLatArray();
        log.info("经纬度：{}",lngLatArray);
        // 这里注意如果在所有分类下 是需要优先展示 推荐类型 和推荐数值
        Wrapper<Merchant> merchantWrapper = new QueryWrapper<Merchant>()
                // 前端用户 限定分类
                .eq(searchParam.getActivityCategoryId() != null, "category_id", searchParam.getActivityCategoryId())
                .eq("status", MerchantStatusEnum.up.getValue())
                // 前端用户 限定城市
                .eq(searchParam.getCityCode() != null, "code_city", searchParam.getCityCode())
                .select(lngLatArray == null ? "*" :
                        String.format("*,ST_Distance_Sphere(ST_GeomFromText('POINT(%f %f)',4326), location) AS distance", lngLatArray[0], lngLatArray[1]))
//                .select("*,ST_Distance_Sphere(ST_GeomFromText('POINT(120.20204 30.186620)',4326), location) AS distance")
                // 排序 智能排序 1级排序优先报名中 2级距离升序 3级 价格升序 4级 创建时间降序
                .orderBy(searchParam.getSortType() == 1, true, "recommend_type")
                .orderBy(searchParam.getSortType() == 1, true, "recommend_index")
                .orderBy(searchParam.getSortType() == 1 && lngLatArray != null, true, "distance")
                .orderBy(searchParam.getSortType() == 1, false, "id")
                // 排序 距离排序
                .orderBy(searchParam.getSortType() == 2 && lngLatArray != null, true, "distance")
                .orderBy(searchParam.getSortType() == 2, true, "recommend_type")
                .orderBy(searchParam.getSortType() == 2, true, "recommend_index")
                .orderBy(searchParam.getSortType() == 2, false, "id");

        Page<Merchant> merchantPage = merchantService.page(page, merchantWrapper);
        if(CollectionUtils.isEmpty(merchantPage.getRecords())) {
            return page;
        }
        List<ActivityCategory> categoryList = activityCategoryService.list(null);
        // 汇总相关的 商家
        List<Long> merchantIdList = merchantPage.getRecords().stream().map(Merchant::getId).collect(Collectors.toList());
        // 读取相关产品
        List<MerchantProduct> productList = merchantProductService.list(
                new QueryWrapper<MerchantProduct>().in("merchant_id", merchantIdList)
                        .eq("status", MerchantProductStatusEnum.up.getValue())
                        .eq("valid", true).orderByAsc("weight")
        );
        // 构造返回数据
        List<MerchantVO> merchantVOList = new ArrayList<>();
        merchantPage.getRecords().forEach(item ->{
            MerchantVO merchantVO = convertMerchantVoInList(item, categoryList);

            List<MerchantProduct> productList1 = productList.stream().filter(DO->DO.getMerchantId().compareTo(item.getId()) ==0).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(productList1)) {
                merchantVO.setMerchantProductVO(appProductService.convert(productList1.get(0)));
            }
            merchantVOList.add(merchantVO);
        });

        page.setRecords(merchantVOList);

        return page;
    }

    private MerchantVO convertMerchantVoInList(Merchant merchant, List<ActivityCategory> categoryList) {
        MerchantVO merchantVO = new MerchantVO();
        BeanUtils.copyProperties(merchant, merchantVO);
        merchantVO.setDistanceShow(DistanceUtil.getDistanceString(merchant.getDistance()));
        merchantVO.setRecommendType(merchant.getRecommendType());
        // 筛选 分类
        List<ActivityCategory> categoryListOne = categoryList.stream().filter(item->item.getId().equals(merchant.getCategoryId())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(categoryListOne)) {
            merchantVO.setCategoryName(categoryListOne.get(0).getName());
            merchantVO.setCategoryIcon(categoryListOne.get(0).getIconPic());
        }
        return merchantVO;
    }

    private MerchantVO convertMerchantVoInDetail(Merchant merchant, List<ActivityCategory> categoryList) {
        MerchantVO merchantVO = new MerchantVO();
        BeanUtils.copyProperties(merchant, merchantVO);
        // 标签
        merchantVO.setTagVOList(MerchantConvert.convertOnlyShowTagList(merchant.getTagJson()));
        // 筛选 分类
        List<ActivityCategory> categoryListOne = categoryList.stream().filter(item->item.getId().equals(merchant.getCategoryId())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(categoryListOne)) {
            merchantVO.setCategoryName(categoryListOne.get(0).getName());
            merchantVO.setCategoryIcon(categoryListOne.get(0).getIconPic());
        }
        // 处理图片分割问题
        if (StringUtils.isNotEmpty(merchant.getPhotoList())) {
            String picList[] = merchant.getPhotoList().split(",");
            List<String> picConvertList = Arrays.stream(picList).collect(Collectors.toList());
            merchantVO.setPhotoListV2(StringUtils.join(picConvertList,"|"));
        }
        if (StringUtils.isNotEmpty(merchant.getLegalPersonList())) {
            String picList[] = merchant.getLegalPersonList().split(",");
            List<String> picConvertList = Arrays.stream(picList).collect(Collectors.toList());
            merchantVO.setLegalPersonListV2(StringUtils.join(picConvertList,"|"));
        }
        merchantVO.setDistanceShow(DistanceUtil.getDistanceString(merchant.getDistance()));
        merchantVO.setRecommendType(merchant.getRecommendType());
        // 详情页屏蔽
        merchantVO.setLegalPersonList(null);
        merchantVO.setLegalPersonTel(null);
        merchantVO.setLegalPersonTel(null);
        return merchantVO;
    }

    /***
     * 参照分类 推荐数据
     * @param categoryId
     * @return
     */
    public List<MerchantVO> getRecMerchantListByCategory(Long categoryId) {
        // 按照城市推荐
        AppLocationDTO appLocationDTO = appAreaService.getAppLocationVo(false);
        //获取授权的经纬度
        Double lngLatArray[] = tokenService.getLngLatArray();
        // 这里注意如果在所有分类下 是需要优先展示 推荐类型 和推荐数值
        Wrapper<Merchant> merchantWrapper = new QueryWrapper<Merchant>()
                // 前端用户 限定分类
                .eq("category_id", categoryId)
                // 按照城市限定
                .eq(appLocationDTO.getCodeCity() != null, "code_city", appLocationDTO.getCodeCity())
                .select(lngLatArray == null ? "*" :
                        String.format("*,ST_Distance_Sphere(ST_GeomFromText('POINT(%f %f)',4326), location) AS distance", lngLatArray[0], lngLatArray[1]))

                .orderByAsc("recommend_type")
                .orderByAsc("recommend_index")
                .orderByDesc( "id").last(" limit 5");

        List<Merchant> merchantList = merchantService.list(merchantWrapper);
        if(CollectionUtils.isEmpty(merchantList)) {
            return null;
        }
        // 汇总相关的 商家
        List<Long> merchantIdList = merchantList.stream().map(Merchant::getId).collect(Collectors.toList());
        // 读取相关产品
        List<MerchantProduct> productList = merchantProductService.list(
                new QueryWrapper<MerchantProduct>().in("merchant_id", merchantIdList)
                        .eq("status", MerchantProductStatusEnum.up.getValue())
                        .eq("valid", true).orderByAsc("weight")
        );
        List<ActivityCategory> categoryList = activityCategoryService.list(null);
        // 构造返回数据
        List<MerchantVO> merchantVOList = new ArrayList<>();
        merchantList.forEach(item ->{
            MerchantVO merchantVO = convertMerchantVoInList(item, categoryList);

            List<MerchantProduct> productList1 = productList.stream().filter(DO->DO.getMerchantId().compareTo(item.getId()) ==0).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(productList1)) {
                merchantVO.setMerchantProductVO(appProductService.convert(productList1.get(0)));
            }
            merchantVOList.add(merchantVO);

        });
        return merchantVOList;
    }

    public MerchantVO getMerchantDetail(Long merchantId) {
        List<ActivityCategory> categoryList = activityCategoryService.list(null);

        Merchant merchant = merchantService.getById(merchantId);
        if(merchant == null) {
            throw new ServiceException("商家信息不存在");
        }
        if(merchant.getStatus().intValue() == MerchantStatusEnum.dowm.getValue()) {
            throw new ServiceException("当前商家已下架");
        }
        MerchantVO merchantVO = convertMerchantVoInDetail(merchant, categoryList);

        return merchantVO;
    }

    public List<MerchantVO> getRecMerchantListByMerchantId(Long merchantId) {
        Merchant merchant = merchantService.getById(merchantId);
        if (merchant == null) {
            throw new ServiceException("指定的商户不存在");
        }
        List<ActivityCategory> categoryList = activityCategoryService.list(null);
        List<MerchantVO> merchantVOList = new ArrayList<>();
        MerchantVO merchantVO = convertMerchantVoInList(merchant, categoryList);
        MerchantProduct merchantProduct = merchantProductService.getOne(
                new QueryWrapper<MerchantProduct>().eq("merchant_id", merchantId)
                        .eq("status", MerchantProductStatusEnum.up.getValue())
                        .eq("valid", true).orderByAsc("weight"),false);
        // 这里需要指定一个产品
        merchantVO.setMerchantProductVO(appProductService.convert(merchantProduct));
        merchantVOList.add(merchantVO);
        List<MerchantVO> merchantVOS = getRecMerchantListByCategory(merchant.getCategoryId());
        // 构造返回数据

        if (!CollectionUtils.isEmpty(merchantVOS)) {
            // 汇总相关的 商家
            List<Long> merchantIdList = merchantVOS.stream().map(MerchantVO::getId).collect(Collectors.toList());
            // 读取相关产品
            List<MerchantProduct> productList = merchantProductService.list(
                    new QueryWrapper<MerchantProduct>().in("merchant_id", merchantIdList)
                            .eq("status", MerchantProductStatusEnum.up.getValue())
                            .eq("valid", true).orderByAsc("weight")
            );
            merchantVOS.forEach(item->{
                // 排除掉一样的
                if(merchant.getId().longValue() != item.getId().longValue()) {

                    List<MerchantProduct> productList1 = productList.stream().filter(DO->DO.getMerchantId().compareTo(item.getId()) ==0).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(productList1)) {
                        item.setMerchantProductVO(appProductService.convert(productList1.get(0)));
                    }
                    merchantVOList.add(item);
                }
            });
        }
        return merchantVOList;
    }

    public List<MerchantVO> getRecMerchantListByProductId(Long productId) {
        MerchantProduct merchantProduct = merchantProductService.getById(productId);
        if (merchantProduct == null) {
            throw new ServiceException("指定的商品不存在");
        }
        Merchant merchant = merchantService.getById(merchantProduct.getMerchantId());
        List<ActivityCategory> categoryList = activityCategoryService.list(null);
        List<MerchantVO> merchantVOList = new ArrayList<>();
        MerchantVO merchantVO = convertMerchantVoInList(merchant, categoryList);
        // 这里需要指定一个产品
        merchantVO.setMerchantProductVO(appProductService.convert(merchantProduct));
        merchantVOList.add(merchantVO);
        List<MerchantVO> merchantVOS = getRecMerchantListByCategory(merchant.getCategoryId());
        // 构造返回数据
        if (!CollectionUtils.isEmpty(merchantVOS)) {
            // 汇总相关的 商家
            List<Long> merchantIdList = merchantVOS.stream().map(MerchantVO::getId).collect(Collectors.toList());
            // 读取相关产品
            List<MerchantProduct> productList = merchantProductService.list(
                    new QueryWrapper<MerchantProduct>().in("merchant_id", merchantIdList)
                            .eq("status", MerchantProductStatusEnum.up.getValue())
                            .eq("valid", true).orderByAsc("weight")
            );
            merchantVOS.forEach(item->{
                // 排除掉一样的
                if(merchant.getId().longValue() != item.getId().longValue()) {
                    List<MerchantProduct> productList1 = productList.stream().filter(DO->DO.getMerchantId().compareTo(item.getId()) ==0).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(productList1)) {
                        item.setMerchantProductVO(appProductService.convert(productList1.get(0)));
                    }
                    merchantVOList.add(item);
                }
            });
        }
        return merchantVOList;
    }
}
